package aure.jslib;

import java.io.IOException;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.mozilla.javascript.Context;
import org.mozilla.javascript.Scriptable;

/**
 * Servlet that binds rhino to the servlet engine.
 * 
 * It runs /WEB-INF/js/init.js when the servlet is loaded and
 * service.js when each request arrives.
 */
public class RhinoServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private Scriptable initialScope = null;
	
	@Override
	public void init(ServletConfig config) throws ServletException {
		super.init(config);
		Context cx = Context.enter();
		try {
			Scriptable scope = cx.initStandardObjects();
			StaticHelper.addJavaObjectToScope(scope, "servlet", this);
			StaticHelper.addJavaObjectToScope(scope, "servletConfig", config);
			
			StaticHelper.initRequireInScope(cx, scope);
			StaticHelper.runScript(cx, "init.js", scope);
			
			this.initialScope = scope;
		} finally {
			Context.exit();
		} 
	}
	
	@Override
	protected void doDelete(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		this.myService(req, resp);
	}
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		this.myService(req, resp);
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		this.myService(req, resp);
	}
	
	@Override
	protected void doPut(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		this.myService(req, resp);
	}
	
	protected void myService(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		Context cx = Context.enter();
		try {
			Scriptable scope = cx.initStandardObjects();
			scope.setParentScope(this.initialScope);
			
			StaticHelper.addJavaObjectToScope(scope, "servletRequest", req);
			StaticHelper.addJavaObjectToScope(scope, "servletResponse", resp);
			
			StaticHelper.runScript(cx, "service.js", scope);
		} finally {
			Context.exit();
		}
	}
}
